package com.dhcc.core.framework.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;

import cn.hutool.core.util.StrUtil;

/**
 * Json工具类
 * 
 * @ClassName: JsonUtil
 * @Description: 描述
 * @author: cyf
 * @date: 2018年1月2日 上午9:35:35
 */
public class JsonUtil {
    private static final SerializeConfig config;

    static {
        config = new SerializeConfig();
    }

    private static final SerializerFeature[] features = { SerializerFeature.WriteMapNullValue, // 输出空置字段
        SerializerFeature.WriteNullListAsEmpty, // list字段如果为null，输出为[]，而不是null
        SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null，输出为0，而不是null
        SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null，输出为false，而不是null
        SerializerFeature.WriteNullStringAsEmpty, // 字符类型字段如果为null，输出为""，而不是null
        SerializerFeature.BrowserCompatible,
        SerializerFeature.PrettyFormat,
    };

    // 读文件，返回JsonObject
    public static JSONObject readFileToJsonObj(String path) {
        String sets = JsonUtil.readFile(path);// 获得json文件的内容
        JSONObject jo = JSONObject.parseObject(sets);// 格式化成json对象
        return jo;
    }

    // 读文件，返回字符串
    public static String readFile(String path) {
        File file = new File(path);
        BufferedReader reader = null;
        String laststr = "";
        try {
            // System.out.println("以行为单位读取文件内容，一次读一整行：");
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                // 显示行号
                if (StringUtils.isNotBlank(tempString) && (!StringUtils.equals(tempString.substring(0, 0), "#"))) {
                    laststr = laststr + tempString;
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
        return laststr;
    }

    /**
     * 创建JSONObject
     * 
     * @return JSONObject
     */
    public static JSONObject createObj() {
        return new JSONObject();
    }

    /**
     * 创建 JSONArray
     * 
     * @return JSONArray
     */
    public static JSONArray createArray() {
        return new JSONArray();
    }

    /**
     * JSON字符串转JSONObject对象
     * 
     * @param jsonStr
     *            JSON字符串
     * @return JSONObject
     */
    public static JSONObject parseObj(String jsonStr) {
        return JSONObject.parseObject(jsonStr);
    }

    /**
     * JSON字符串转JSONObject对象<br>
     * 此方法会忽略空值，但是对JSON字符串不影响
     * 
     * @param obj
     *            Bean对象或者Map
     * @return JSONObject
     */
    public static JSONObject parseObj(Object obj) {
        return JSONObject.parseObject(JSONObject.toJSONString(obj));
    }

    /**
     * JSON字符串转JSONArray
     * 
     * @param jsonStr
     *            JSON字符串
     * @return JSONArray
     */
    public static JSONArray parseArray(String jsonStr) {
        return JSONArray.parseArray(jsonStr);
    }

    /**
     * JSON字符串转JSONArray
     * 
     * @param arrayOrCollection
     *            数组或集合对象
     * @return JSONArray
     * @since 3.0.8
     */
    public static JSONArray parseArray(Object arrayOrCollection) {
        return JSONArray.parseArray(JSONArray.toJSONString(arrayOrCollection));
    }

    /**
     * 转换对象为JSON<br>
     * 支持的对象：<br>
     * String: 转换为相应的对象<br>
     * Array Collection：转换为JSONArray<br>
     * Bean对象：转为JSONObject Map对象：转为JSONObject
     * 
     * @param obj
     *            对象
     * @return JSON
     */
    public static JSON parse(Object obj) {
        if (null == obj) {
            return null;
        }

        JSON json = null;
        if (obj instanceof JSON) {
            json = (JSON) obj;
        } else if (obj instanceof String) {
            String jsonStr = ((String) obj).trim();
            if (jsonStr.startsWith("[")) {
                json = parseArray(jsonStr);
            } else {
                json = parseObj(jsonStr);
            }
        } else if (obj instanceof Collection || obj.getClass().isArray()) {// 列表
            json = parseArray(obj);
        } else {// 对象
            json = parseObj(obj);
        }

        return json;
    }

    /**
     * 转换为JSON字符串
     * 
     * @param obj
     *            被转为JSON的对象
     * @return JSON字符串
     */
    public static String toJsonStr(Object obj) {
        if (obj instanceof String) {
            return (String) obj;
        }
        return JSON.toJSONString(obj, config, features);
    }
    public static String toJson(Object obj) {
        if (obj instanceof String) {
            return (String) obj;
        }
        return JSON.toJSONString(obj, config, features);
    }

    /**
     * JSON字符串转为实体类对象，转换异常将被抛出
     * 
     * @param <T>
     *            Bean类型
     * @param jsonString
     *            JSON字符串
     * @return 实体类对象
     * @since 3.1.2
     */
    public static Object toBean(String text) {
        return JSON.parse(text);
    }

    /**
     * JSON字符串转为实体类对象，转换异常将被抛出
     * 
     * @param <T>
     *            Bean类型
     * @param jsonString
     *            JSON字符串
     * @param beanClass
     *            实体类对象
     * @return 实体类对象
     * @since 3.1.2
     */
    public static <T> T toBean(String text, Class<T> clazz) {
        return JSON.parseObject(text, clazz);
    }

    /**
     * 转为实体类对象，转换异常将被抛出
     * 
     * @param <T>
     *            Bean类型
     * @param json
     *            JSONObject
     * @param beanClass
     *            实体类对象
     * @return 实体类对象
     */
    public static <T> T toBean(JSONObject json, Class<T> beanClass) {
        return toBean(json.toJSONString(), beanClass);
    }

    /**
     * 将JsonStr转换为Bean的数组
     * 
     * @return List
     * @since 4.0.7
     */
    public static <T> Object[] toArray(String JsonStr) {
        return toArray(JsonStr, null);
    }

    /**
     * 将JsonStr转换为Bean的数组
     * 
     * @return List
     * @since 4.0.7
     */
    public static <T> Object[] toArray(String text, Class<T> clazz) {
        return JSON.parseArray(text, clazz).toArray();
    }

    /**
     * 将JSONArray转换为Bean的List，默认为ArrayList
     * 
     * @param JsonStr
     *            JsonStr
     * @param elementType
     *            List中元素类型
     * @return List 
     * @since 4.0.7
     */
    public static <T> List<T> toList(String JsonStr, Class<T> clazz) {
        return JSON.parseArray(JsonStr, clazz);
    }
    
    /**
     * 对象转换成JSON对象
     * 
     * @param obj
     *            需要转换的对象
     * @return 对象的string字符
     */
    public static JSONArray listToJsonArray(List<?> obj) {
        return JSONArray.parseArray(JSONArray.toJSONString(obj));
    }
    

    /**
     * 将JSONArray转换为Bean的List，默认为ArrayList
     * 
     * @param jsonArray
     *            JSONArray
     * @param elementType
     *            List中元素类型
     * @return List
     * @since 4.0.7
     */
    public static <T> List<T> toList(JSONArray jsonArray, Class<T> elementType) {
        return null == jsonArray ? null : toList(jsonArray.toJSONString(), elementType);
    }

    /**
     * 将JSONArray对象转换成list集合
     * 
     * @param jsonArr
     * @return
     */
    public static List<Object> toList(JSONArray jsonArr) {
        List<Object> list = new ArrayList<Object>();
        for (Object obj : jsonArr) {
            if (obj instanceof JSONArray) {
                list.add(toList((JSONArray) obj));
            } else if (obj instanceof JSONObject) {
                list.add(toMap((JSONObject) obj));
            } else {
                list.add(obj);
            }
        }
        return list;
    }

    /**
     * 将json字符串转换成map对象
     * 
     * @param json
     * @return
     */
    public static Map<String, Object> toMap(String json) {
        Map<String, Object> result = new HashMap<String, Object>();
        if(isJsonArray(json)){
            JSONArray arr = JSON.parseArray(json);
            result=toMap(arr);
        }else if(isJsonObj(json)){
            JSONObject obj = JSONObject.parseObject(json);
            result=toMap(obj);
        }
        return result;
    }
    
    public static Map<String, Object> jsonToMap(String json) {
        Map<String, Object> result = new HashMap<String, Object>();
        if(isJsonArray(json)){
            JSONArray arr = JSON.parseArray(json);
            result=toMap(arr);
        }else if(isJsonObj(json)){
            JSONObject obj = JSONObject.parseObject(json);
            result=toMap(obj);
        }
        return result;
    }

    /**
     * 将JSONObject转换成map对象
     * 
     * @param json
     * @return
     */
    public static Map<String, Object> toMap(JSONObject obj) {
        Set<?> set = obj.keySet();
        Map<String, Object> map = new HashMap<String, Object>(set.size());
        for (Object key : obj.keySet()) {
            Object value = obj.get(key);
            if (value instanceof JSONArray) {
                map.put(key.toString(), toList((JSONArray) value));
            } else if (value instanceof JSONObject) {
                map.put(key.toString(), toMap((JSONObject) value));
            } else {
                map.put(key.toString(), obj.get(key));
            }

        }
        return map;
    }

    /**
     * 将JSON数组转换为Map  [{name:xxx,value:xxx},{name:xxx,value:xxx}]
     * @param arr
     * @return
     */
    public static Map<String, Object> toMap(JSONArray arr) {
        Map<String, Object> map = new HashMap<String, Object>(arr.size());
        for(int i=0;i<arr.size();i++){
             JSONObject obj = arr.getJSONObject(i);
             if(obj.containsKey("name")){
                 map.put(obj.getString("name"),obj.getString("value"));
             }
        }
        return map;
    }
    /**
     * 是否为JSON字符串，首尾都为大括号或中括号判定为JSON字符串
     * 
     * @param str
     *            字符串
     * @return 是否为JSON字符串
     * @since 3.3.0
     */
    public static boolean isJson(String str) {
        return isJsonObj(str) || isJsonArray(str);
    }

    /**
     * 是否为JSONObject字符串，首尾都为大括号或中括号判定为JSON字符串
     * 
     * @param str
     *            字符串
     * @return 是否为JSON字符串
     * @since 3.3.0
     */
    public static boolean isJsonObj(String str) {
        if (StrUtil.isBlank(str)) {
            return false;
        }
        return StrUtil.isWrap(str.trim(), '{', '}');
    }

    /**
     * 是否为JSONObject字符串，首尾都为大括号或中括号判定为JSON字符串
     * 
     * @param str
     *            字符串
     * @return 是否为JSON字符串
     * @since 3.3.0
     */
    public static boolean isJsonArray(String str) {
        if (StrUtil.isBlank(str)) {
            return false;
        }
        return StrUtil.isWrap(str.trim(), '[', ']');
    }

}
